package com.ray.export.thread;

import com.alibaba.fastjson.JSON;
import com.ray.export.exception.RunnerException;
import com.ray.export.runner.Runner;
import com.ray.export.runner.RunnerFactory;
import com.ray.export.runner.RunnerResult;
import com.ray.export.strategy.result.SuccessResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StopWatch;

/**
 * @author bo shen
 * @Description: 启动线程驱动
 * @Class: ThreadEventListener
 * @Package com.ray
 * @date 2019/11/26 11:05
 * @company <p>杭州传化陆鲸科技有限公司</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Component
@Slf4j
public class ThreadEventListener implements ApplicationListener<ThreadEvent>{
    @Autowired(required = false)
    private PlatformTransactionManager platformTransactionManager;
    @Autowired(required = false)
    private TransactionDefinition transactionDefinition;

    @Override
    @Async
    public void onApplicationEvent(ThreadEvent event) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        //在有事务管理的情况下
        //开始事务配置
        TransactionStatus transaction = null;
        if (!ObjectUtils.isEmpty(platformTransactionManager)) {
            log.info("任务开启事务");
            // 获得事务状态
            transaction = platformTransactionManager.getTransaction(transactionDefinition);
        }
        try {
            //异步执行前执行
            RunnerResult result = event.doRun(event.getRunnerResult());
            if (!ObjectUtils.isEmpty(platformTransactionManager)) {
                platformTransactionManager.commit(transaction);
            }
            log.info("线程异步执行结果：{},结果参数：{}", result.getStatus(), JSON.toJSONString(result.getResult()));
        } catch (RunnerException e) {
            if (!ObjectUtils.isEmpty(platformTransactionManager)) {
                log.info("事务回滚：{}",event.getDataModel().getTemplateCode());
                platformTransactionManager.rollback(transaction);
            }
            log.info("线程异步执行结果异常:{}", e.getMessage());
            RunnerResult result = new RunnerResult();
            result.setDataModel(event.getDataModel());
            result.setRunType(e.getRunType());
            result.setResult(new SuccessResult(false,e.getMessage()));
            result.setAsynchronou(false);
            callError(event, result);
        }catch (Exception e){
            if (!ObjectUtils.isEmpty(platformTransactionManager)) {
                log.info("事务回滚：{}",event.getDataModel().getTemplateCode());
                platformTransactionManager.rollback(transaction);
            }
            log.info(e.getMessage());
        }
        stopWatch.stop();
        log.info("任务:[{}]线程异步执行结束，耗时：{}",event.getDataModel().getTemplateCode(),stopWatch.getTotalTimeMillis());
    }

    private void callError(ThreadEvent event, RunnerResult result) {
        Runner runner = RunnerFactory.getRunner(Error.class);
        runner.doRunner(event.getAnnotation(), event.getDataModel(), result);
    }
}
